package com.example.demo.Controller.Opus;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.demo.Bean.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.Entity.Rate.Rate;
import com.example.demo.Entity.Topic.Topic;
import com.example.demo.Entity.User.User;
import com.example.demo.Entity.User_Rate.UserRate;
import com.example.demo.ServiceImpl.Opus.OpusServiceImpl;
import com.example.demo.Entity.Opus.Opus;
import com.example.demo.ServiceImpl.Rate.RateServiceImpl;
import com.example.demo.ServiceImpl.Topic.TopicServiceImpl;
import com.example.demo.ServiceImpl.User.UserServiceImpl;
import com.example.demo.ServiceImpl.User_Rate.UserRateServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/opus")
public class OpusController {
    @Resource
    private OpusServiceImpl opusService;
    @Resource
    private RateServiceImpl rateService;
    @Resource
    private UserServiceImpl userService;
    @Resource
    private TopicServiceImpl topicService;
    @Resource
    private UserRateServiceImpl userRateService;

    @PostMapping
    public Boolean save(@RequestBody Opus opus) {
        System.out.println(opus.toString());
        return opusService.saveOrUpdate(opus);
    }

    @DeleteMapping("/{id}")
    public Boolean delete(@PathVariable(value = "id") Integer id) {
        return opusService.removeById(id);
    }

    @GetMapping
    public R findAll() {
        return R.ok().put("opusList", opusService.list());
    }

    @GetMapping("/{id}")
    public R findOne(@PathVariable(value = "id") Integer id) {
        return R.ok().put("opus", opusService.getById(id));
    }

    @GetMapping("/page")
    public R findPage(@RequestParam(value = "pageNum") Integer pageNum,
                      @RequestParam(value = "pageSize") Integer pageSize, @RequestParam(value = "uid") Integer uid) {
        List<Opus> opuses;
        if (userService.getById(uid).getType().equals("管理员")) {
            opuses = opusService.list();
            List<List<Integer>> list = new ArrayList<>();
            extracted(opuses, list);
            return R.ok().put("opusPage", opuses).put("RateList", list).put("total", opusService.count());
        } else {
            LambdaQueryWrapper<UserRate> userRateLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userRateLambdaQueryWrapper.eq(UserRate::getUid, uid);
            userRateLambdaQueryWrapper.eq(UserRate::getIsrate,0);
            Page<UserRate> userRatePage = userRateService.page(new Page<>(pageNum, pageSize), userRateLambdaQueryWrapper);
            if (userRatePage.getRecords().isEmpty()) {
                List<Object> objects = new ArrayList<>();
                return Objects.requireNonNull(R.ok().put("opusPage", objects).put("RateList", objects)).put("total", objects);
            } else {
                opuses = opusService.listByIds(userRatePage.getRecords().stream()
                        .map(UserRate::getOid)
                        .collect(Collectors.toList()));
                List<List<Integer>> list = new ArrayList<>();
                extracted(opuses, list);
                return R.ok().put("opusPage", opuses).put("RateList", list).put("total", userRatePage.getTotal());
            }
        }
    }

    private void extracted(List<Opus> opuses, List<List<Integer>> list) {
        opuses.forEach(i -> {
            LambdaQueryWrapper<Rate> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Rate::getOid, i.getId());
            List<Rate> rates = rateService.list(queryWrapper);
            List<Integer> integers = new ArrayList<>();
            rates.forEach(j -> {
                integers.add(j.getUid());
            });
            list.add(integers);
        });
    }

    @GetMapping("/ratepage")
    public R findRatePage(@RequestParam(value = "pageNum") Integer pageNum,
                          @RequestParam(value = "pageSize") Integer pageSize) {
        Page<Rate> page = rateService.page(new Page<>(pageNum, pageSize));
        List<User> users = new ArrayList<>();
        List<Topic> topics = new ArrayList<>();
        List<UserRate>userRates=userRateService.list();
        page.getRecords().forEach(i -> {
            users.add(userService.getById(i.getUid()));
            LambdaQueryWrapper<UserRate>userRateLambdaQueryWrapper=new LambdaQueryWrapper<>();
            userRateLambdaQueryWrapper.eq(UserRate::getOid, i.getOid());
            userRateLambdaQueryWrapper.eq(UserRate::getUid, i.getUid());
            userRates.add(userRateService.getOne(userRateLambdaQueryWrapper));
            Opus opus = opusService.getById(i.getOid());
            topics.add(topicService.getById(opus.getTid()));
        });
        return R.ok().put("ratePage", page).put("UserList", users).put("TopicList", topics).put("UserRateList", userRates);
    }

    @GetMapping("/rate/{id}")
    public R findOneRate(@PathVariable(value = "id") Integer id) {
        LambdaQueryWrapper<Opus> opusQueryWrapper = new LambdaQueryWrapper<>();
        opusQueryWrapper.eq(Opus::getTid, id);
        Opus opus = opusService.getOne(opusQueryWrapper);
        LambdaQueryWrapper<Rate> rateQueryWrapper = new LambdaQueryWrapper<>();
        rateQueryWrapper.eq(Rate::getOid, opus.getId());
        List<User> users = new ArrayList<>();
        List<Rate> rates = rateService.list(rateQueryWrapper);
        List<UserRate> userRates = new ArrayList<>();
        if (rates.size() > 0) {
            LambdaQueryWrapper<UserRate> userRateLambdaQueryWrapper = new LambdaQueryWrapper<>();
            userRateLambdaQueryWrapper.eq(UserRate::getOid,rates.get(0).getOid());
            userRates=userRateService.list(userRateLambdaQueryWrapper);
            rates.forEach(i -> {
                users.add(userService.getById(i.getUid()));
            });
        }
        return R.ok().put("rate", rates).put("UserList", users).put("UserRateList", userRates);
    }
}